﻿
Imports std

Partial Public Class distributor
    Protected Class distribute_parameter
        Inherits pair(Of ijob, vector(Of pair(Of UInt32, ijob)))

        Public Shared Shadows Function make_pair(ByVal i As ijob,
                                                 ByVal j As vector(Of pair(Of UInt32, ijob))) As distribute_parameter
            Return New distribute_parameter() With {.first = i, .second = j}
        End Function
    End Class

    Protected Class aggregate_parameter
        Inherits pair(Of indexedJob(), ijob)

        Public Shared Shadows Function make_pair(ByVal i() As indexedJob, ByVal j As ijob) As aggregate_parameter
            Return New aggregate_parameter() With {.first = i, .second = j}
        End Function
    End Class

    Protected Delegate Function distribute_delegate(ByVal inputJob As ijob,
                                                    ByVal targetJobs As vector(Of pair(Of UInt32, ijob))) As Boolean
    Protected Delegate Function aggregate_delegate(ByVal targetJobs() As indexedJob,
                                                   ByVal inputJob As ijob) As Boolean

    Private Shared Function distribute_to_switcher(ByVal i As distribute_delegate) _
                                                  As _do(Of distribute_parameter, Boolean)
        If i Is Nothing Then
            Return Nothing
        Else
            Return Function(ByRef arg As distribute_parameter) As Boolean
                       assert(Not arg Is Nothing)
                       Return i(arg.first, arg.second)
                   End Function
        End If
    End Function

    Private Shared Function aggregate_to_switcher(ByVal i As aggregate_delegate) _
                                                 As _do(Of aggregate_parameter, Boolean)
        If i Is Nothing Then
            Return Nothing
        Else
            Return Function(ByRef arg As aggregate_parameter) As Boolean
                       assert(Not arg Is Nothing)
                       Return i(arg.first, arg.second)
                   End Function
        End If
    End Function

    Protected Class distribute_switcher(Of T As IComparable(Of T))
        Inherits switcher(Of T, distribute_parameter, Boolean)

        Public Shadows Class condition_action
            Inherits switcher(Of T, distribute_parameter, Boolean).condition_action

            Public Sub New(ByVal condition As T, ByVal action As distribute_delegate)
                MyBase.New(condition, distribute_to_switcher(action))
            End Sub
        End Class

        Public Sub New(ByVal default_action As distribute_delegate,
                       ByVal ParamArray selectors() As condition_action)
            MyBase.New(distribute_to_switcher(default_action), selectors)
        End Sub

        Public Sub New(ByVal ParamArray selectors() As condition_action)
            MyBase.New(selectors)
        End Sub

        Public Shadows Function execute(ByVal condition As T,
                                        ByVal inputJob As ijob,
                                        ByVal targetJobs As vector(Of pair(Of UInt32, ijob))) As Boolean
            Return MyBase.execute(condition, distribute_parameter.make_pair(inputJob, targetJobs))
        End Function
    End Class

    Protected Class aggregate_switcher(Of T As IComparable(Of T))
        Inherits switcher(Of T, aggregate_parameter, Boolean)

        Public Shadows Class condition_action
            Inherits switcher(Of T, aggregate_parameter, Boolean).condition_action

            Public Sub New(ByVal condition As T, ByVal action As aggregate_delegate)
                MyBase.New(condition, aggregate_to_switcher(action))
            End Sub
        End Class

        Public Sub New(ByVal default_action As aggregate_delegate,
                       ByVal ParamArray selectors() As condition_action)
            MyBase.New(aggregate_to_switcher(default_action), selectors)
        End Sub

        Public Sub New(ByVal ParamArray selectors() As condition_action)
            MyBase.New(selectors)
        End Sub

        Public Shadows Function execute(ByVal condition As T,
                                        ByVal targetJobs() As indexedJob,
                                        ByVal inputJob As ijob) As Boolean
            Return MyBase.execute(condition, aggregate_parameter.make_pair(targetJobs, inputJob))
        End Function
    End Class
End Class
